home *** CD-ROM | disk | FTP | other *** search
- /* Some of the code in this file was originally based on the following file:
- * gateway.c : Paul Healy, EI9GL, 900818
- *
- * Rewrote forwarding mechanism to use "X-Forwarded-To" paradigm instead of
- * "X-BBS-To", added timer support, etc. Anders Klemets, SM0RGV, 901009.
- */
- /* Mods by G1EMM and WG7J */
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <time.h>
- #include "global.h"
- #include "config.h"
- #include "bm.h"
- #include "mailbox.h"
- #include "smtp.h"
- #include "cmdparse.h"
- #include "proc.h"
- #include "socket.h"
- #include "timer.h"
- #include "usock.h"
- #include "netuser.h"
- #include "ax25.h"
- #include "netrom.h"
- #include "nr4.h"
- #include "files.h"
- #include "mailfor.h"
-
- #ifdef MBFWD
-
- #define NOSUBCHANNEL (NUMMBX + 10)
- extern int MbForwarded;
- extern char MboxId[], MboxIdFwd[];
- extern int BBSdump;
- extern int MbBID, MbMID;
- #define ISPROMPT(s) (strlen(s) > 1 && s[strlen(s)-2] == '>')
- static struct timer fwdtimer;
- unsigned subchannels[NUMMBX];
- int subchannelusage[NUMMBX];
- int lastSessionSkipped;
- int FWDmode = 1, FWDpersonal = 1, FWDbulletins = 1, FWDreverse = 1;
- #ifdef LZW
- int FWDlzw = 1;
- #else
- int FWDlzw = 0;
- #endif
-
- static char *findident __ARGS((char *str, int n, char *result));
- static void sendmsg __ARGS((struct mbx *m,int msgn,char *thebid));
- char *mbxtime __ARGS((char *line));
- static int fwdinit __ARGS((struct mbx *m));
- static char *fwdanybbs __ARGS((struct mbx *m,int *poll));
- static int timeok __ARGS((char *line));
- static void fwdtick __ARGS((void *v));
- static void fwdproc __ARGS((int, void *, void *));
- static int isconnbbs __ARGS((struct mbx *m));
- static void startfwd __ARGS((int a,void *v1,void *v2));
- static int openconn __ARGS((int argc,char *argv[],void *p));
- static int sendmsgtobbs __ARGS((struct mbx *m,int msgn,char *dest,int bulletin));
- static int makecl __ARGS((struct mbx *m,int msgn,char *dest,char *line,char *subj,char *bid,int *bul));
- static char *grabtext __ARGS((char *from,char *to,int marker));
- void forwardingSummary __ARGS((void));
- extern char *nntp_name_expansion __ARGS((char *name));
-
-
- #ifdef LZW
- static int
- dolzw(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&FWDlzw,"Forward using lzw",argc,argv);
- }
- #endif
-
-
- static int
- domode(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&FWDmode,"Forwarding enabled",argc,argv);
- }
-
-
- static int
- dopersonal(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&FWDpersonal,"Forwarding Personal Messages",argc,argv);
- }
-
-
- static int
- dobulletins(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&FWDbulletins,"Forwarding Bulletins",argc,argv);
- }
-
-
- static int
- doreverse(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&FWDreverse,"Reverse Forwarding Enabled",argc,argv);
- }
-
- static int
- dosummary(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- forwardingSummary();
- return 0;
- }
-
- static int
- dostatus(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i, first = 0;
-
- dobulletins (0, 0, 0);
- #ifdef LZW
- dolzw (0, 0, 0);
- #endif
- domode (0, 0, 0);
- dopersonal (0, 0, 0);
- doreverse (0, 0, 0);
-
- /* also give forwarding in progress report */
- for(i = 0; i < NUMMBX; ++i) {
- if(Mbox[i] == NULLMBX)
- continue;
- if ((Mbox[i]->state == MBX_FORWARD) || (Mbox[i]->state == MBX_REVFWD)) {
- if (!first) {
- tprintf ("\nActive Forwarding Sessions:\n");
- first = 1;
- }
- tprintf (" %-9s - %sForwarding\n", Mbox[i]->name, (Mbox[i]->state == MBX_REVFWD) ? "Reverse " : "");
- }
- }
- return (0);
- }
-
-
- static struct cmds DFAR FWDcmds[] = {
- "bulletins", dobulletins, 0, 0, NULLCHAR,
- #ifdef LZW
- "lzw", dolzw, 0, 0, NULLCHAR,
- #endif
- "mode", domode, 0, 0, NULLCHAR,
- "personal", dopersonal, 0, 0, NULLCHAR,
- "reverse", doreverse, 0, 0, NULLCHAR,
- "status", dostatus, 0, 0, NULLCHAR,
- "summary", dosummary, 0, 0, NULLCHAR,
- NULLCHAR,
- };
-
-
- int
- doforward(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return subcmd(FWDcmds,argc,argv,p);
- }
-
-
-
- /***************************************************************************
- findident copies the 'n'th alphanumeric sequence from 'str' to result.
- It returns a ptr to result. It returns "\0" for missing identifier etc.
- Uses isalnum macro to decide on alphanumeric/non-alnum status.
- */
- static char *
- findident(str, n, result)
- char *str, *result;
- int n;
- {
- int count; /* current identifier */
- count = 0;
- *result = '\0';
- while ( (count<n) && (*str!='\0') ) { /* Process alnum or non alnum seq */
- while ( (*str!='\0') && (!isalnum(*str)) ) /* Get rid of ';:.@%"# etc */
- str++;
- if ( (*str!='\0') && isalnum(*str) ) { /* this is an alnum seq */
- count++;
- while ( (*str!='\0') && (isalnum(*str) || (*str=='_')) )
- if (count==n)
- *result++ = *str++;
- else str++;
- if (count==n)
- *result = '\0';
- }
- }
- return result;
- }
-
- extern char *Mbhaddress;
- extern char *Mbfwdinfo;
- extern char *Mbqth;
- extern int MbRSTYLE;
- extern char *Mbzip;
- extern int Mbsmtptoo;
- extern int Mbfullsvc;
- extern int UtcOffset;
- extern char shortversion[];
-
-
- static int
- checkone (line,str,sub)
- char *line, *str, *sub;
- {
- char *cp;
-
- if (!strnicmp (line, str, strlen(str)) && (cp = strstr (line, Hostname)) != NULLCHAR) {
- strcpy (cp, sub);
- return 1;
- }
- return 0;
- }
-
-
- int
- adaptaddress (line)
- char *line;
- {
- char buf[60], *cp;
- int retval = 0;
-
- pax25(buf,Mycall);
- if((cp = strchr(buf,'-')) != NULLCHAR)
- *cp = '\0'; /* remove SSID */
- strcat (buf, (Mbhaddress != NULLCHAR) ? Mbhaddress : "");
- strcat (buf, "\n");
- if (checkone (line, Hdrs[XMAILGROUP], buf))
- return 1;
- if (checkone (line, Hdrs[ERRORSTO], buf))
- return 1;
- return (checkone (line, Hdrs[REPLYTO], buf));
- }
-
-
- /**************************************************************************/
- /* sendmsg() modified to send the R: line always.
- * also added some additional strings like qth and zipcode etc. to R: line.
- * Original SMTP headers get forwarded optionally.
- * 920114 - WG7J
- */
-
- static void
- sendmsg(m,msgn,thebid)
- struct mbx *m;
- int msgn;
- char *thebid;
- {
- char buf[LINELEN], tb[LINELEN], *cp;
- int len,rec = 0; /* rec is line-counter */
- long cnt;
- unsigned int msgid=0; /* message id number - WG7J */
- int col, ccnt;
- char c;
-
- /*point to start of this message in file*/
- fseek(m->mfile,m->mbox[msgn].start,0);
- /*get message size*/
- cnt = m->mbox[msgn].size;
-
- /* If the data part of the message starts with "R:" the RFC-822
- * headers will not be forwarded. Instead we will add an R:
- * line of our own.
- */
- /* ALWAYS forward with "R:" line */
- for(;;) {
- /*read a line*/
- if(fgets(buf,sizeof(buf),m->mfile) == NULLCHAR)
- break;
- pwait (NULL);
- /*adjust message character count*/
- cnt -= strlen(buf);
- if(rec == 1) {
- /* look at the line following Received:
- * This has the ID followed by ' ; date&time in arpa-format'
- */
- /*get the message number from the ID line - WG7J*/
- if((cp=strstr(buf,"AA"))!= NULLCHAR)
- /*what follows is the message-number*/
- msgid = atoi(cp+2);
- /*get the ARPA format date/time string*/
- if((cp = strchr(buf,';')) != NULLCHAR){
- strcpy(tb,cp+1); /* point to the date of receipt */
- }
- /*ALWAYS send the R: line */
- pax25(buf,Mycall);
- if((cp = strchr(buf,'-')) != NULLCHAR)
- *cp = '\0'; /* remove SSID */
- /*If mbox header is off, don't send the R: line*/
- if (Mbfullsvc) {
- if(!MbRSTYLE) {
- usprintf(m->user,"R:%s @:%s%s%s ", mbxtime(tb), buf,
- (Mbhaddress != NULLCHAR) ? "." : "",
- (Mbhaddress != NULLCHAR) ? Mbhaddress : "");
- if (Mbfwdinfo)
- usprintf(m->user, "[%s] ", Mbfwdinfo);
- if (Mbqth)
- usprintf(m->user,"%s ", Mbqth);
- if (MbMID)
- usprintf(m->user,"#:%u ", msgid);
- if (Mbzip)
- usprintf(m->user,"Z:%s ", Mbzip);
- if (MbBID && (thebid[0] == '$'))
- usprintf(m->user, "$:%s", &thebid[1]);
- usprintf(m->user, "\n");
- } else
- usprintf(m->user, "R:%s %d@%s%s%s\n", mbxtime(tb), msgid, buf, (Mbhaddress) ? "." : "",
- (Mbhaddress) ? Mbhaddress : "");
- }
- break;
- }
- /* The first Received: line is the one that we have added */
- if(!rec && htype(buf) == RECEIVED)
- ++rec;
- }
- /*Go past the SMTP headers to the data of the message.
- *Check if we need to forward the SMTP headers!
- *920114 - WG7J
- */
- for(;;) {
- if(fgets(buf,sizeof(buf),m->mfile) == NULLCHAR)
- break;
- pwait (NULL);
- cnt -= strlen(buf);
- if(*buf == '\n') /* last header line */
- break;
- if (adaptaddress (buf))
- usputs(m->user,buf);
- else if(Mbsmtptoo) { /*YES, forward SMTP headers TOO !*/
- switch(htype(buf)) {
- case XFORWARD: /* Do not forward the "X-Forwarded-To:" lines */
- case STATUS: /* Don't forward the "Status:" line either */
- case BBSTYPE:
- case SUBJECT:
- case TO:
- case DATE:
- break;
- case FROM:
- /* Don't forward the "From: " line either.
- * make it ">From: "
- */
- cp = strdup(buf);
- strcpy(buf,">");
- strcat(buf,cp);
- free(cp); /*note fall-through*/
- default:
- usputs(m->user,buf);
- }
- }
- }
- /* If this is a message that originated locally,
- * there are NO other R: headers
- * in that case send a '\n',
- * to separate the text from our R:-header - WG7J
- */
- if(fgets(buf,sizeof(buf),m->mfile) == NULLCHAR)
- return; /* NO text ??? */
- cnt -= strlen(buf);
- if(strncmp(buf,"R:",2)) /* NO R: found! */
- /*Now a blank line, separating our headers and body*/
- usputs(m->user,"\n");
- if (!strncmp (Hdrs[RRECEIPT], buf, strlen(Hdrs[RRECEIPT]))) { /* return receipt line */
- if (!isarea (m->area)) /* only send if not a bulletin */
- usputs(m->user,buf);
- else
- fgets(buf,sizeof(buf),m->mfile); /* eat the blank line following */
- cnt -= strlen(buf);
- }
- else
- usputs(m->user,buf);
-
- /* the rest of the message is treated below */
- #ifdef nope
- do {
- len = min(cnt,sizeof(buf)-1);
- if(fread(buf,1,len,m->mfile) != len)
- break;
- pwait (NULL);
- cnt -= len;
- buf[len] = '\0';
- usputs(m->user,buf);
- } while(cnt);
- #else
- col = 0;
- while (!feof(m->mfile) && cnt > 0) {
- for (col = 0; col < MAXBUF;) {
- c = getc(m->mfile);
- cnt--;
- if (feof(m->mfile) || cnt == 0) /* end this line */
- break;
- if (c == '\t') {
- ccnt = col + 8 - (col & 7);
- if (ccnt >= MAXBUF) /* end this line */
- break;
- while (col < ccnt)
- buf[col++] = ' ';
- } else {
- if (c == '\n')
- break;
- buf[col++] = c;
- }
- }
- if(col < MAXBUF)
- buf[col++] = '\n';
- buf[col] = '\0';
- usputs(m->user,buf);
- pwait (NULL);
- }
- #endif
- }
-
- /* Parse a line for date and time in Arpanet format
- * (Day, day Month year hh:mm:ss Zone) and return it in mailbox format
- * (yymmdd/hhmmz)
- */
- char *
- mbxtime(line)
- char *line;
- {
- extern char *Months[];
- static char buf[13];
- char *cp;
- int year,month,day,hour,minute,maxdays;
-
- cp = line;
- while(isspace(*cp)) /* skip initial blanks */
- ++cp;
- if(*cp == '\0')
- return NULLCHAR;
- if(strlen(cp) < 22)
- return NULLCHAR;
- cp += 5;
- day = atoi(cp);
- if(*(++cp) != ' ')
- ++cp;
- ++cp;
- for(month=0; month < 12; ++month)
- if(strnicmp(Months[month],cp,3) == 0)
- break;
- if(month == 12)
- return NULLCHAR;
-
- /* Get things, and adjust for GMT/UTC time - WG7J */
- month++;
- year = atoi(cp+4);
- hour = atoi(cp + 7);
- minute = atoi(cp + 10);
-
- if(UtcOffset != 0) {
- hour -= UtcOffset;
- /* See if we went past midnight */
- if(hour > 23) {
- hour -= 24;
- ++day;
- /*Check for next month*/
- if(month == 2) { /*February, check leap-year*/
- if((year%4) == 0)
- maxdays = 29;
- else
- maxdays = 28;
- } else {
- if((month%2) == 0)
- maxdays = 30;
- else
- maxdays = 31;
- }
- if(day > maxdays) { /*adjust month*/
- day = 1;
- if(++month == 13) { /*next year*/
- month = 1;
- year++;
- }
- }
- } else
- if(hour < 0) { /*previous day !*/
- hour += 24;
- if(--day == 0) { /*previous month*/
- if(--month == 0) { /*previous year*/
- year--;
- month = 12;
- }
- if(month == 2) { /* February, check leap year */
- if((year%4) == 0)
- day = 29;
- else
- day = 28;
- } else {
- if((month%2) == 0)
- day = 30;
- else
- day = 31;
- }
- }
- }
- }
-
- sprintf(buf,"%02d%02d%02d/%02d%02dz",year,month,day,hour,minute);
- return buf;
- }
-
- static char *
- grabtext(from, to, marker)
- char *from, *to;
- int marker;
- {
- while (*from!=marker)
- *to++ = *from++;
- *to = '\0';
- return from+1;
- }
-
- /* Makes a command line and returns -1 if the message cannot be sent. */
- static int
- makecl(m, msgn, dest, line, subj, bid, bul)
- struct mbx *m;
- int msgn; /* Message number */
- char *dest; /* Destination address to use instead of To: line */
- char *line, *subj; /* Buffers to keep command line and subject */
- char *bid; /* Buffer to keep bid */
- int *bul; /* True if message is in public message area */
- {
- int bulletin = *bul;
- int foundbid = 0;
- char to[LINELEN], atbbs[LINELEN], from[LINELEN], buf[LINELEN], *cp;
-
- if(m->mfile == NULLFILE)
- return -1;
-
- if(!bulletin && (m->mbox[msgn].status & BM_READ))
- return -1; /* the message was already read */
- fseek(m->mfile,m->mbox[msgn].start,0);
- *bid = *to = *atbbs = *from = '\0';
- if(subj != NULLCHAR)
- *subj = '\0';
- m->stype = bulletin ? 'B' : 'P'; /* default to SB or SP */
- while (fgets(buf,sizeof(buf),m->mfile)) {
- if (buf[0] == '\n')
- break; /* envelope finished */
- switch (htype(buf)) {
- case TO:
- /* The following code tries to parse "To: " lines where the
- * address looks like any of the following: "to@atbbs",
- * "<to@atbbs>", "<to%atbbs@host>" and with possible spaces
- * surrounding the '<>' characters.
- */
- if((cp = getaddress(buf,0)) == NULLCHAR)
- break;
- strcpy(to,cp);
- if((cp = strchr(to,'%')) != NULLCHAR) { /* look for a '%' */
- strcpy(atbbs,cp + 1);
- *cp = '\0'; /* "to" ends at the '%' character */
- }
- else { /* no '%' but maybe a '@'? */
- if((cp = strchr(to,'@')) != NULLCHAR) {
- strcpy(atbbs,cp + 1);
- *cp = '\0'; /* "to" ends at the '@' character */
- }
- }
- if(*atbbs != '\0') /* either '%' or '@' found */
- /* cut "atbbs" at the first '@' character */
- for(cp = atbbs; *cp != '\0'; ++cp)
- if(*cp == '@') {
- *cp = '\0';
- break;
- }
- /* "to" or "atbbs" should not be more than 6 characters (ALEN).
- * If "to" is too long, it might simply be because the area name
- * is longer than 6 characters, but it might also be because
- * the address on the To: line is in an obscure format that we
- * failed to parse (eg '!' character notation.)
- */
- if(strlen(to) > ALEN) {
- /* Play safe and set "to" and "atbbs" to the area name */
- strcpy(to,m->area);
- strcpy(atbbs,m->area);
- }
-
- /* why would we want to add an atbbs if the message doesn't have one originally ?!?! */
- #if 0
- if(*atbbs == '\0')
- strcpy(atbbs,to);
- #endif
-
- to[ALEN] = '\0';
- /* Only if the BBS supports "hierarchical routing designators"
- * is the atbbs field allowd to be longer than 6 characters and
- * have dots in it.
- */
- if((m->sid & MBX_HIER_SID) == 0) {
- atbbs[ALEN] = '\0'; /* 6 character limit */
- if((cp = strchr(atbbs,'.')) != NULLCHAR)
- *cp = '\0'; /* cut "atbbs" at first dot */
- }
- break;
- case MSGID:
- /* The following code distinguishes between two different types
- * of Message-IDs: <abcde@callsign.bbs> and <abcde@host.domain>.
- * The first type is converted to $abcde and the second to
- * $abcde_host.domain. This preserves compability with BBSes.
- */
- if((cp = getname(buf)) == NULLCHAR)
- break;
- bid[0] = '$';
- strcpy(&bid[1],cp);
- cp = strchr(bid,'@');
- /* A trailing ".bbs" indicates that the Message-ID was generated
- * from a BBS style message, and not a RFC-822 message.
- */
- if(cp != NULLCHAR && stricmp(&bid[strlen(bid) - 4], ".bbs") == 0) {
- *cp = '\0'; /*retain the bid given by user*/
- foundbid = 1; /* Indicate we found a 'real' bid - WG7J */
- } else {
- /*This is a message with no bid, MSGID is <msg#@hostname>
- *make this BID style '$msg#_host'
- *ie. replace @ with _ and
- *cut off after first part of hostname - WG7J
- */
- *cp = '_';
- if((cp = strchr(cp,'.')) != NULLCHAR)
- *cp = '\0';
- }
- bid[13] = '\0'; /* BIDs should be no longer than 13 bytes */
- break;
- case SUBJECT:
- if(subj != NULLCHAR) {
- (void) grabtext(buf+9, subj, '\n');
- /* Make sure subject isn't empty - WG7J */
- cp = subj;
- while(*cp == ' ' || *cp == '\t')
- cp++;
- if(*cp == '\0')
- strcpy(subj,"None");
- }
- break;
- case FROM:
- if((cp = getaddress(buf,0)) != NULLCHAR) {
- if (!strnicmp (cp,"REQSVR",6) || !strnicmp (cp, "MAILER-DAEMON", 13)) { /* MAILER-DAEMON going out->call sign */
- pax25(buf,Mycall);
- cp = strchr (buf, '-');
- if (cp)
- *cp = 0;
- strcpy (from, buf);
- } else
- findident(cp, 1, from); /* cp points to from@domain */
- from[ALEN] = '\0'; /* 6 character limit */
- }
- break;
- case XFORWARD:
- if((cp = getaddress(buf,0)) == NULLCHAR)
- break;
- if(stricmp(m->name,cp) == 0) {
-
- /* This message has already been forwarded, abort */
- return -1;
- }
- break;
- case BBSTYPE:
- m->stype = buf[16];
- /* if it comes from a NTS area,
- * always send as traffic, ie 'ST' - WG7J
- */
- if(!strnicmp(m->area,"nts",3))
- m->stype = 'T';
- if(m->stype == 'B') {
- bulletin = 1;
- *bul = 1;
- }
- break;
- default:
- break;
- }
- }
- /* Check for an invalid RFC-822 header */
- if((to[0] == '\0' && ((dest != NULLCHAR && *dest == '\0') ||
- dest == NULLCHAR)) || from[0] == '\0')
- return -1;
-
- if(line != NULLCHAR) {
- if(dest != NULLCHAR && *dest != '\0'){
- /* strip off hierarchical routing designators from the predefined
- * destination address if they are not supported
- */
- if((m->sid & MBX_HIER_SID) == 0 && (cp = strchr(dest,'.')) !=
- NULLCHAR)
- *cp = '\0';
- sprintf(line, "S%c %s < %s ", m->stype, dest, from);
- }
- else
- sprintf(line, "S%c %s%s%s < %s ", m->stype, to, (*atbbs) ? " @ " : "", atbbs, from);
- #ifdef nope
- /* This fixes the problem with personal MIDs being the same with
- * messages generated from aliases, RMAIL, or mail-groups. Changes
- * the bid from $abcde_host.domain to $abcde_destinationuser. - KO4KS
- */
- if (!bulletin && (m->sid & MBX_MID)) {
- if ((cp = strrchr (bid, '_')) != NULLCHAR) {
- *cp++;
- if (!strnicmp (Hostname, cp, strlen(cp))) {
- *(cp-1) = '%';
- if(dest != NULLCHAR && *dest != '\0')
- strcpy (cp, dest);
- else
- strcpy (cp, to);
- bid[13] = '\0';
- if ((cp = strchr (bid, '.')) != NULLCHAR)
- *cp = '\0';
- }
- }
- }
- #endif
-
- /* This keeps us from adding a MID to someone else's message */
- if (!foundbid) { /* if one wasn't found, but GENERATED */
- fgets(buf,sizeof(buf),m->mfile); /* get first data line */
- if (!strnicmp (buf, "R:", 2)) /* if it has at least one "R:" line */
- bid[0] = '\0'; /* blank out the MID */
- }
-
- /* convert the bid to upper case for compatability with BBSs */
- strupr (bid);
-
- /* Add the bid to bulletins,
- * AND ALSO to anything that came in with a bid !
- * Takes care off duplicate 'SP SYSOP@xxx $BID' problems - WG7J
- * ALSO add it to ALL messages if the remote system supports MID's - WG7J
- */
- /* if((m->sid & MBX_MID) || ((bulletin || foundbid) & (m->sid & MBX_SID))) */
- if((m->sid & MBX_MID) || (bulletin && (m->sid & MBX_SID)))
- strcat(line,bid);
- strcat(line,"\n");
- }
- return 0;
- }
-
- static int /* 0 = ok, -1 = problem so disc */
- sendmsgtobbs(m, msgn, dest, bulletin)
- struct mbx *m;
- int msgn;
- char *dest; /* Optional destination address to override To: line */
- int bulletin;
- {
- int result = -1;
- char line[64], subj[256], thebid[LINELEN];
-
- if(makecl(m, msgn, dest, line, subj, thebid, &bulletin) == -1)
- return 0; /* do not forward this particular message */
- tputs(line); /* Send mail offer to bbs */
- rip(line);
- usflush(m->user);
- if (recvline (m->user, m->line, MBXLINE) != -1 ) {
- if (m->line[0] == 'O' || m->line[0] == 'o' || (m->sid & MBX_SID) == 0) {
- /* Got 'OK' or any line if the bbs is unsofisticated */
- tprintf("%s\n", subj);
- sendmsg(m,msgn,thebid); /* send the message */
- tputs("/EX\n"); /* was 0x1a */
- usflush(m->user);
- /* get F> for a good deliver */
- while (recvline (m->user, m->line, MBXLINE) != -1 )
- if (ISPROMPT(m->line)) {
- log(m->user,"MBOX bbs mail sent: %s ", line);
- #ifdef notagain
- if(bulletin)
- m->mbox[msgn].status |= BM_FORWARDED;
- else {
- #endif
- if(!bulletin) {
- m->mbox[msgn].status |= BM_DELETE;
- statusCtl (m->area, "ctl", &m->mbox[msgn], msgn, 0);
- m->change |= CHG_DELETE;
- }
- result = 0;
- MbForwarded++;
- break;
- }
- } else { /* OK response not received from bbs */
- if (m->line[0] == 'N' || m->line[0] == 'n') { /* 'NO' respone */
- log(m->user,"MBOX bbs mail refused: %s\n %s",line,m->line);
- #ifdef notagain
- /* Mark refused message as forwarded if it is a bulletin.
- * The message was probably a duplicate. Non-bulletin
- * messages are sent without BID, so they cannot be dected
- * as duplicates. The reason why it was refused is probably
- * because the address was invalid. Retry later.
- */
- if(bulletin) {
- m->mbox[msgn].status |= BM_FORWARDED;
- statusCtl (m->area, "ctl", &m->mbox[msgn], msgn, 0);
- /* m->change = 1; */
- }
- #endif
- result = 0; /* don't want it, so skip it! */
- }
- /* should get a F> here */
- while (recvline (m->user, m->line, MBXLINE) != -1 )
- if (ISPROMPT(m->line)) {
- result = 0;
- break;
- }
- }
- } /* OK or NO here */
- if (m->stype != 'B')
- msgiddelete (&thebid[1]);
- return result;
- }
-
-
- /* Forward messages from one message area. */
- static int
- fwdthisarea (m, fwd, area, newto)
- struct mbx *m;
- FILE *fwd;
- char *area, *newto;
- {
- int bulletin;
- long bid, pos = 0, save;
- int index, changed = 0, i;
- int err = 0;
- char *cp;
- struct let *cmsg;
- char line[80];
-
- pwait (NULL);
- bulletin = isarea(area); /* public area */
- if (bulletin && !FWDbulletins)
- return err;
- if (!bulletin && !FWDpersonal)
- return err;
- rewind (fwd);
- while(!err && fgets(line,MBXLINE,fwd) != NULLCHAR) {
- fflush (fwd);
- pwait (NULL);
- if (*line != '*') { /* if not already done */
- if ((cp = strpbrk(&line[1]," \t")) != NULLCHAR)
- *cp++ = '\0';
- if (!stricmp (area, &line[1])) { /* only if for us */
- bid = atol (cp);
- if (!changed) { /* if not already changed */
- changearea(m,area, (int) 1);
- changed = 1;
- }
- index = 0;
- for (cmsg = &m->mbox[1],i = 1; i <= m->nmsgs; i++, cmsg++)
- if (bid == cmsg->bid) {
- index = i;
- break;
- }
- if (index && !(cmsg->status & (BM_ONHOLD | BM_DELETE))) {
- if(sendmsgtobbs(m, index, newto, bulletin) == -1)
- err = 1; /* abort */
- }
- if (!index || (!err && !(cmsg->status & BM_ONHOLD))) {
- clearerr(fwd);
- save = ftell (fwd);
- fseek (fwd, pos, SEEK_SET);
- fputc ('*', fwd); /* mark as done! */
- fflush (fwd);
- fseek (fwd, save, SEEK_SET);
- }
- }
- }
- pos = ftell (fwd); /* get new backup position */
- }
- return err;
- }
-
-
- /* This is the main entry point for reverse forwarding. It is also used
- * for normal, "forward", forwarding.
- */
- int
- dorevfwd(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char oldarea[64], *area, *cp;
- struct mbx *m;
- int err = 0;
- unsigned i = NOSUBCHANNEL;
- FILE *fwd;
- long thesize, theend, thetop, newsize;
- char name[256];
-
- m = (struct mbx *)p;
- /* indicate we are doing reverse forwarding, if we are not already
- * doing normal forwarding.
- */
- if(m->state != MBX_FORWARD) {
- if (!FWDreverse)
- goto notallowed;
- m->state = MBX_REVFWD;
- if ((m->sid & MBX_SID) && m->mysize)
- smtptick(NULL); /* wake SMTP to send that mail */
- m->mysize = 0;
- }
- if(fwdinit(m) != -1) {
- strcpy(oldarea,m->area);
- sprintf (name, "%s/%s.fwd", Mailspool, m->name);
- nntp_name_expansion (name);
- strcat (name, ".fwd");
- if((fwd = fopen(name,UPDATE_TEXT)) == NULLFILE)
- return 0; /* shouldn't happen except with reverse fwd */
- log(m->user,"MBOX %sforwarding mail to: %s ", (m->state == MBX_REVFWD) ? "reverse " : "", m->name);
- thesize = filelength(fileno(fwd)); /* so we know if any new */
- thetop = ftell (m->tfile);
- while(!err) {
- if (m->privs & EXCLUDED_CMD)
- break;
- newsize = filelength(fileno(fwd));
- if (thesize != newsize) {
- /* if new mail came in to forward, start back
- up at the top of the areas to forward.
- This allows you to push personal traffic
- at highest priority */
- thesize = newsize;
- fseek (m->tfile, thetop, 0);
- }
- if (fgets(m->line,MBXLINE,m->tfile) == NULLCHAR)
- break;
- if(*m->line == '-') /* end of record reached */
- break;
- if(*m->line == '#') /* skip comments */
- continue;
- if (*m->line == '=') { /* subchannel number */
- i = atoi (&m->line[1]);
- if (i > NUMMBX || subchannelusage[i] == subchannels[i]) { /* maxed out */
- err = 1;
- i = NOSUBCHANNEL;
- continue;
- } else
- subchannelusage[i]++;
- }
- rip(m->line); /* adds extra null at end */
- if ((cp = strpbrk(m->line," \t")) != NULLCHAR)
- *cp = '\0';
- if(*m->line == '\0' || *m->line == '.' || *m->line == '+' || *m->line == '@')
- continue;
- /* get the optional destination field, cp will point
- * at null byte if it is missing.
- */
- cp = &m->line[strlen(m->line)] + 1;
- while(*cp != '\0' && isspace(*cp)) /* strip blanks */
- ++cp;
- cp = strdup(cp);
- area = strdup(m->line);
- err = fwdthisarea (m, fwd, area, cp);
- free(cp);
- free(area);
- }
- fclose(m->tfile);
- m->tfile = NULLFILE;
- if(*oldarea != '\0')
- changearea(m,oldarea, (int) 1);
- theend = filelength(fileno (fwd));
- if (!err && thesize == theend) {
- rewind (fwd);
- while(fgets(m->line,MBXLINE,fwd) != NULLCHAR) {
- pwait (NULL);
- if (*m->line != '*') { /* if not already done */
- err = 1;
- break;
- }
- }
- fclose (fwd);
- if (!err)
- remove (name);
- } else
- fclose (fwd);
- }
- if (i != NOSUBCHANNEL)
- subchannelusage[i]--;
- if(m->state == MBX_FORWARD)
- return 0;
- notallowed:
- tprintf("*** Done\n");
- /* if((m->sid & MBX_RLI_SID) || (m->sid & MBX_FBB)) */ /* disconnect if it is a W0RLI or FBB bbs */
- if(m->sid & MBX_RLI_SID) /* disconnect if it is a W0RLI bbs */
- return domboxbye(0,NULL,m);
- return 0;
- }
-
- /* Read the forward file for a record for the connected BBS. If found,
- * return 0 if this is the right time to forward, m->tfile is left pointing
- * at the first message area to be forwarded.
- * returns -1, also, if nothing queued for forwarding.
- */
- static int
- fwdinit(m)
- struct mbx *m;
- {
- char host[80];
- char name[256];
- int start = 1;
-
- if((m->tfile = fopen(Forwardfile,READ_TEXT)) == NULLFILE)
- return -1;
- while(fgets(m->line,MBXLINE,m->tfile) != NULLCHAR) {
- if(*m->line == '\n')
- continue;
- if(*m->line == '#')
- continue;
- /* lines starting with '-' separate the forwarding records */
- if(*m->line == '-') {
- start = 1;
- continue;
- }
- if(start) {
- start = 0;
- /* get the name of this forwarding record */
- findident(m->line,1,host);
- if(stricmp(m->name,host) == 0) {
- if(!timeok(m->line))
- break;
- sprintf (name, "%s/%s.fwd", Mailspool, host);
- if (access (name, 0)) /* nothing in this area! */
- break;
- /* eat the connect command line */
- do {
- fgets(m->line,MBXLINE,m->tfile);
- } while (*m->line == '#' || *m->line == '\n');
- return 0;
- }
- }
- }
- fclose(m->tfile);
- m->tfile = NULLFILE;
- return -1;
- }
- /* Read the forward file for a record for the connected BBS. If found,
- * determine if this is the right time to forward, and return the command
- * line to establish a forwarding connection. m->tfile is left pointing
- * at the first message area to be forwarded.
- */
- static char *
- fwdanybbs(m, poll)
- struct mbx *m;
- int *poll;
- {
- char host[80];
- int start = 1, i;
- if(m->tfile == NULLFILE && (m->tfile = fopen(Forwardfile,READ_TEXT))
- == NULLFILE)
- return NULLCHAR;
- *poll = 0; /* Default to no polling */
- while(fgets(m->line,MBXLINE,m->tfile) != NULLCHAR) {
- if(*m->line == '\n')
- continue;
- if(*m->line == '#')
- continue;
- /* lines starting with '-' separate the forwarding records */
- if(*m->line == '-') {
- start = 1;
- continue;
- }
- if(start) {
- start = 0;
- /* get the name of this forwarding record */
- findident(m->line,1,host);
- strcpy(m->name,host);
- if(!timeok(m->line))
- continue; /* too late or too early */
- /* Check for polling - WG7J */
- i=2;
- findident(m->line,2,host);
- while(*host) {
- if(*host == 'P' || *host == 'p') {
- *poll = 1;
- break;
- }
- i++;
- findident(m->line,i,host);
- }
- /* get the connect command line */
- do {
- fgets(m->line,MBXLINE,m->tfile);
- } while (*m->line == '#' || *m->line == '\n');
- return strdup(m->line);
- }
- }
- fclose(m->tfile);
- m->tfile = NULLFILE;
- return NULLCHAR;
- }
-
- /* get any groups of four digits that specify the begin and ending hours of
- * forwarding. Returns 1 if forwarding may take place.
- */
- static int
- timeok(line)
- char *line;
- {
- char hours[80], *now;
- long t;
- int t1, t2, pos = 2;
- findident(line,pos++,hours);
- if(*hours == '\0')
- return 1; /* no digits default to 0023, ie. anytime */
- time(&t);
- now = ctime(&t) + 11;
- *(now + 2) = '\0';
- while(*hours != '\0') {
- t1 = (*hours - '0') * 10 + (*(hours+1) - '0');
- t2 = (*(hours+2) - '0') * 10 + (*(hours+3) - '0');
- if(atoi(now) >= t1 && atoi(now) <= t2)
- return 1; /* right in time */
- findident(line,pos++,hours); /* get next group if any */
- }
- return 0; /* too early or too late */
- }
-
- int
- dombtimer(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc < 2){
- tprintf("Forwarding timer: %lu/%lu\n",
- read_timer(&fwdtimer)/1000L,
- dur_timer(&fwdtimer)/1000L);
- return 0;
- }
- stop_timer (&fwdtimer); /* just in case */
- fwdtimer.func = (void (*)())fwdtick;/* what to call on timeout */
- fwdtimer.arg = NULL; /* dummy value */
- set_timer(&fwdtimer,atol(argv[1])*1000L); /* set timer duration */
- start_timer(&fwdtimer); /* fire it up */
- return 0;
- }
-
- int
- dombkick(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- fwdtick (NULL);
- return 0;
- }
-
-
- /* MDMII: fwdproc is the old fwdtick. But, since it can call mspause, which is
- * very very bad for timer functions :-( this has been converted to a server.
- */
- static void
- fwdtick(v)
- void *v;
- {
- start_timer(&fwdtimer); /* and restart the timer */
- if (FWDmode)
- if (newproc ("forward daemon", 2048, fwdproc, 0, NULL, NULL, 0) == NULLPROC)
- log (-1, "Couldn't start Forwarding process");
- }
-
-
- /* called when the forward timer expires or explicitly by dombkick() */
- static void
- fwdproc(nerf,v1,v2)
- int nerf; /* unused */
- void *v1, *v2; /* unused */
- {
- char *cc, *cp;
- struct mbx *m;
- unsigned i;
- int bulletin, poll, skip = 0;
- char name[256];
- time_t t;
-
- if(Mtrace)
- printf("mailbox: forward started\n");
- if((m = newmbx()) == NULLMBX){
- if(Mtrace)
- printf("forward: unable to start new maibox\n");
- return;
- }
- time(&t);
- m->logontime = (long) t;
- m->user = Curproc->output;
- m->name[0] = 0;
- m->state = MBX_TRYING;
- lastSessionSkipped = 0;
- while((cc = fwdanybbs(m,&poll)) != NULLCHAR) {
- i = NOSUBCHANNEL;
- if(Mtrace)
- printf("mailbox: examining '%s'\n", m->name);
- pwait (NULL);
- if(isconnbbs(m)) {
- /* already connected to this BBS, skip it */
- skip = 1;
- if (Mtrace)
- printf ("fwd: '%s' already connected\n", m->name);
- }
- while(fgets(m->line,MBXLINE,m->tfile) != NULLCHAR) {
- if(*m->line == '#')
- continue;
- if(*m->line == '\n')
- continue;
-
- if(*m->line == '-') { /* end of record reached */
- skip = 0;
- break;
- }
- if (*m->line == '=') /* sub-channel info */
- i = atoi (&m->line[1]);
- if((cp = strpbrk(m->line," \t")) != NULLCHAR)
- *cp = '\0';
- if(skip || *m->line == '\0' || *m->line == '.' || \
- *m->line == '+' || *m->line == '@')
- continue;
- pwait (NULL);
- /* If we poll, there is no need to check message area, since this
- * is also done later. It will speed things up here - WG7J
- */
- if (!poll) { /* don't need if polling */
- sprintf (name, "%s/%s.fwd", Mailspool, m->name);
- if(Mtrace)
- printf("mailbox: checking for file '%s'\n", name);
- }
- skip = 1;
- if (poll || !access (name, 0)) {
- if (i != NOSUBCHANNEL || subchannelusage[i] == subchannels[i]) { /* maxed out */
- lastSessionSkipped = 1;
- continue;
- }
- if(Mtrace)
- printf("forward: to %s\n",m->name);
- if (i != NOSUBCHANNEL)
- subchannelusage[i]++;
- newproc("Mbox forwarding", 3072,startfwd, i, (void *)cc,(void *)strdup(m->name),0);
- } else
- free (cc);
- cc = NULLCHAR;
- }
- free(cc);
- }
- exitbbs(m);
- }
-
- /* returns 1 if m->name matches the name of another connected mailbox. */
- static int
- isconnbbs(m)
- struct mbx *m;
- {
- int i;
- for(i = 0; i < NUMMBX; ++i)
- if(Mbox[i] != NULLMBX && Mbox[i] != m &&
- stricmp(m->name,Mbox[i]->name) == 0)
- return 1;
- return 0;
- }
-
- /* possible commands on the command line in the forwarding file */
- static struct cmds cfwdcmds[] = {
- "tcp", openconn, 0, 0, NULLCHAR,
- "telnet", openconn, 0, 0, NULLCHAR,
- #ifdef AX25
- "ax25", openconn, 0, 0, NULLCHAR,
- "connect", openconn, 0, 0, NULLCHAR,
- #endif
- #ifdef NETROM
- "netrom", openconn, 0, 0, NULLCHAR,
- #endif
- NULLCHAR
- };
-
- static void
- fwdcleanup (index, m, string)
- int index;
- struct mbx *m;
- char *string;
- {
- exitbbs(m);
- if(Mtrace && string)
- printf(string, m->name);
- if (index != NOSUBCHANNEL)
- subchannelusage[index]--;
- if (lastSessionSkipped)
- fwdtick (NULL);
- }
-
-
- /* this function is called whenever the forwarding timer expires */
- static void
- startfwd(a,v1,v2)
- int a;
- void *v1, *v2;
- {
- struct mbx *m;
- char *cc;
- int32 timeout;
- int rval;
- char *cp;
- char Continue[MBXLINE];
- time_t t;
-
- cc = (char *) v1;
- if((m = newmbx()) == NULLMBX) {
- free(cc);
- free((char *)v2);
- if (a != NOSUBCHANNEL)
- subchannelusage[a]--;
- return;
- }
- time(&t);
- m->logontime = (long) t;
- strcpy(m->name,(char *)v2);
- free((char *)v2);
- m->state = MBX_TRYING;
- /* open the connection, m->user will be the new socket */
- if(cmdparse(cfwdcmds,cc,(void *)m) == -1) {
- free(cc);
- fwdcleanup (a, m, "forward: unknown protocol\n");
- return;
- }
- free(cc);
- m->state = MBX_FORWARD;
- sockowner(m->user,Curproc);
- close_s(Curproc->output);
- close_s(Curproc->input);
- /* m->user will be closed automatically when this process exits */
- Curproc->output = Curproc->input = m->user;
- /* We'll do our own flushing right before we read input */
- setflush(m->user,-1);
-
- if(fwdinit(m) == -1) {
- /* it is probably not the right time to forward anymore */
- fwdcleanup (a, m, NULLCHAR);
- return;
- }
- /* read the connect script. Lines starting with a dot will be sent
- * to the remote BBS.
- */
- Continue[0] = '\0';
- while((cp=fgets(m->line,MBXLINE,m->tfile)) != NULLCHAR) {
- if (*m->line == '#' || *m->line == '=' || *m->line == '\n')
- continue;
- /* Expanded to do timeouts, and return string recognition - WG7J */
- if(*m->line == '.') { /* send this line */
- tputs(m->line + 1);
- if(Mtrace)
- printf("fwd: %s > %s\n",m->name,m->line+1);
- Continue[0] = '\0'; /* reset reply string */
- } else if(*m->line == '+') { /* string upon wich we continue ! */
- strcpy(Continue,m->line+1);
- rip(Continue); /* get rid of \n */
- } else if(*m->line == '@') { /* string that sets timeout */
- timeout = atoi(m->line+1);
- if(timeout) /* if a valid conversion */
- timeout *= 1000; /* in ms ! */
- else
- timeout = 90*1000L; /* default to 1.5 minutes */
- if(Mtrace)
- printf("fwd: %s, wait %ld < %s\n",m->name,timeout/1000,Continue);
- /* Now do the actual response interpretations */
- alarm(timeout);
- rval = recvline(m->user,m->line,MBXLINE);
- alarm(0L);
- /* Did we timeout, or connection disappear ? */
- if(Mtrace) {
- printf("fwd: %s, rx %d",m->name,rval);
- if(rval >= 0)
- printf(", %s",m->line);
- else
- putchar('\n');
- }
- if((rval < 0) || (strstr(m->line,Continue) == NULLCHAR)) {
- fwdcleanup (a, m, "fwd: %s, aborted!\n");
- return;
- }
- Continue[0] = '\0'; /* reset reply string */
- } else /* must be the end of the script */
- goto go_on;
-
- usflush(m->user); /* send it, if any */
- }
- /* Now we've past all in-between stuff, go talk to the bbs ! */
- go_on:
- usflush(m->user);
- fclose(m->tfile);
- m->tfile = NULLFILE;
-
- /* make sure there is something left ! */
- if(cp == NULLCHAR) {
- fwdcleanup (a, m, "fwd: forward.bbs error!\n");
- return;
- }
- if(Mtrace)
- printf("fwd: %s, script done\n",m->name);
-
- /* read the initial output from the bbs, looking for the SID */
- for(;;) {
- timeout = 120*1000L; /* wait up to 2 minutes for each response line */
- if(Mtrace)
- printf("fwd: %s, wait %ld < %s\n",m->name,timeout/1000,">");
- alarm(timeout);
- rval = recvline(m->user,m->line,MBXLINE);
- alarm(0L);
- if(rval == -1) {
- fwdcleanup (a, m, NULLCHAR);
- return;
- }
- if(ISPROMPT(m->line))
- break;
- if(*m->line == '[') { /* parse the SID */
- rip(m->line);
- mbx_parse(m);
- continue;
- }
- }
- /* Now sync the two ends as telnet password messes them up */
- if(socklen(m->user,0)) /* discard any remaining input */
- recv_mbuf(m->user,NULL,0,NULLCHAR,0);
-
- /* send our SID if the peer announced its SID */
- if(m->sid & MBX_SID) {
- tputs(FWDlzw ? MboxIdFwd : MboxId);
- usflush(m->user);
- #ifdef LZW
- /* If we both support it, go into compression here */
- if (FWDlzw && m->sid & MBX_TNOS)
- togglelzw (m->user, 1);
- #endif
- for(;;) {
- if(recvline(m->user,m->line,MBXLINE) == -1) {
- exitbbs(m);
- return;
- }
- if(ISPROMPT(m->line))
- break;
- }
- }
- /* start the actual forwarding */
- dorevfwd(0,NULL,(void *)m);
- /* ask for reverse forwarding or just disconnect */
- if(((m->sid & MBX_SID) && tputs("F>\n") == -1) ||
- (m->sid & MBX_SID) == 0) {
- fwdcleanup (a, m, NULLCHAR);
- close_s(Curproc->output);
- return;
- }
- usflush(m->user);
- /* parse the commands that are are received during reverse
- * forwarding.
- */
- while(recvline(m->user,m->line,MBXLINE) > 0) {
- if (m->privs & EXCLUDED_CMD)
- break;
- rip(m->line);
- if((rval = mbx_parse(m)) == -2) /* got the "*** Done" command */
- break;
- if (rval && BBSdump) /* we dump for all unknowns! */
- break;
- if (m->privs & EXCLUDED_CMD)
- break;
- tputs("F>\n");
- usflush(m->user);
- }
- #if 0
- /* if((m->sid & MBX_RLI_SID) || (m->sid & MBX_FBB)) { */ /* disconnect if it is a W0RLI or FBB bbs */
- if(m->sid & MBX_RLI_SID) { /* disconnect if it is a W0RLI bbs */
- domboxbye(0,NULL,m);
- return;
- }
- #else
- domboxbye(0,NULL,m);
- #endif
- if ((m->sid & MBX_SID) && m->mysize)
- smtptick(NULL); /* wake SMTP to send that mail */
- fwdcleanup (a, m, NULLCHAR);
- usflush(Curproc->output);
- mspause(500L);
- close_s(Curproc->output);
- }
-
- /* open a network connection based upon information in the cc line.
- * m->user is set to the socket number.
- */
- static int
- openconn(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct mbx *m;
- char sock[MAXSOCKSIZE], *np, alias[AXBUF];
- #ifdef NETROM
- struct nrroute_tab *rp;
- #endif
- union sp sp;
- int len;
-
- m = (struct mbx *)p;
- sp.p = sock;
- if(argc < 2)
- return -1;
- switch(*argv[0]) {
- case 't':
- sp.in->sin_family = AF_INET;
- if((sp.in->sin_addr.s_addr = resolve(argv[1])) == 0)
- return -1;
- /* get the optional port number */
- if(argc > 2)
- sp.in->sin_port = atoip(argv[2]);
- else
- sp.in->sin_port = IPPORT_TELNET;
- if((m->user = socket(AF_INET,SOCK_STREAM,0)) == -1)
- return -1;
- len = sizeof(*sp.in);
- m->family = AF_INET; /*So the user list will be correct! - WG7J */
- break;
- #ifdef AX25
- case 'a':
- case 'c': /* allow 'c' for 'connect' as well */
- if(argc < 3)
- return -1;
- sp.ax->sax_family = AF_AX25;
- strncpy(sp.ax->iface,argv[1],ILEN); /* the interface name */
- setcall(sp.ax->ax25_addr,argv[2]); /* the remote callsign */
- /* no digipeaters for now, use the "ax25 route add" command */
- if((m->user = socket(AF_AX25,SOCK_STREAM,0)) == -1)
- return -1;
- len = sizeof(*sp.ax);
- m->family = AF_AX25; /*So the user list will be correct! - WG7J */
- break;
- #endif /* AX25 */
- #ifdef NETROM
- case 'n':
- /* See if the requested destination could be an alias, and
- * use it if it is. Otherwise assume it is an AX.25
- * address.
- */
- putalias(alias,argv[1],0);
- strupr(argv[1]);
- if ((rp = find_nrboth(alias,argv[1])) == NULLNRRTAB) {
- if(Mtrace)
- tprintf("fwd: Netrom route unavailable - %s\n",argv[1]);
- return -1;
- }
- /* Setup the local side of the connection */
- sp.nr->nr_family = AF_NETROM;
- len = sizeof(*sp.nr);
- if((m->user = socket(AF_NETROM,SOCK_SEQPACKET,0)) == -1) {
- if(Mtrace)
- tprintf("fwd: unable to open netrom socket - %s\n",argv[1]);
-
- return -1;
- }
- memcpy(sp.nr->nr_addr.user,Nr4user,AXALEN);
- memcpy(sp.nr->nr_addr.node,Nr_iface->hwaddr,AXALEN);
- bind(m->user,sp.p,len);
-
- /* Now the remote side */
- memcpy(sp.nr->nr_addr.node,rp->call,AXALEN) ;
- /* The user callsign of the remote station is never
- * used by NET/ROM, but it is needed for the psocket() call.
- */
- memcpy(sp.nr->nr_addr.user,rp->call,AXALEN) ;
-
- m->family = AF_NETROM; /*So the user list will be correct! - WG7J */
- break;
- #endif /* NETROM */
- default:
- return -1;
- }
- sockmode(m->user,SOCK_ASCII);
- if(connect(m->user,sp.p,len) == -1) {
- log(m->user,"MBOX forward failed: %s errno %d",
- sockerr(m->user),errno);
- close_s(m->user);
- return -1;
- }
- return m->user;
- }
-
-
- void
- forwardingSummary()
- {
- int k;
- register FILE *fp;
- char buf[100], *cp;
- int totbul = 0, totper = 0, bul, per;
-
- for (k = 0; k < Numfwds; k++) {
- sprintf(buf,"%s/%s.fwd",Mailspool,MyFwds[k]);
- per = bul = 0;
- if((fp = fopen(buf,READ_TEXT)) != NULLFILE) {
- while (fgets(buf,sizeof(buf),fp) != NULLCHAR)
- if (*buf == ' ') {
- cp = strchr (&buf[1], ' ');
- if (cp) {
- *cp++ = 0;
- if (isarea (&buf[1]))
- bul++;
- else
- per++;
- }
- }
- fclose(fp);
- }
- tprintf ("Queued for forwarding to %-10.10s: Bulletins/Personal (%5d/%-5d)\n", MyFwds[k], bul, per);
- totbul += bul;
- totper += per;
- }
- if (k)
- tprintf ("Total messages to forward : Bulletins/Personal (%5d/%-5d)\n\n", totbul, totper);
- else
- tprintf ("You have no BBS's in your 'forward.bbs' file!\n");
- }
-
-
- int
- AREAlookup (area, index)
- char *area;
- int index;
- {
- FILE *fp;
- int start = 1;
- int checking = 0;
- char *cp;
- char line[80];
- int retval = 0;
-
- /* if(Checklock)
- return retval; */
- if((fp=fopen(Forwardfile,READ_TEXT)) == NULLFILE)
- return retval;
- /*Now scan the forward.bbs file to find bbs's*/
- while(fgets(line,sizeof(line),fp) != NULLCHAR) {
- if(*line == '\n')
- continue;
- if(*line == '#')
- continue;
- if(*line == '.' || *line == '+' || *line == '@' || *line == '=')
- continue;
- /* lines starting with '-' separate the forwarding records */
- if(*line == '-') {
- start = 1;
- checking = 0;
- continue;
- }
- if (checking && !strnicmp (area, line, strlen(area))) {
- cp = &line[strlen(area)];
- if (*cp == ' ' || *cp == '\n' || *cp == '\t') {
- retval = 1;
- break;
- }
- }
- if(start) {
- start = 0;
- if (checking)
- break;
- /* get the name of this forwarding record */
- if((cp=strpbrk(line," \n\t")) != NULLCHAR)
- *cp = '\0';
- if(strlen(line) > FWDBBSLEN)
- continue; /*What kind of bbs-call is this ?*/
- if (!stricmp (MyFwds[index], line))
- checking = 1;
- }
- }
- fclose(fp);
- return retval;
- }
-
-
- #endif /*MBFWD*/
-